#pragma once
#include "../Utils/PlatTypeUtil.h"

enum
{
	// Default allocator alignment. If the default is specified, the allocator applies to engine rules.
	// Blocks >= 16 bytes will be 16-byte-aligned, Blocks < 16 will be 8-byte aligned. If the allocator does
	// not support allocation alignment, the alignment will be ignored.
	DEFAULT_ALIGNMENT = 0,

	// Minimum allocator alignment
	MIN_ALIGNMENT = 8,
};

struct PtrInfo
{
	uint64 mSize;
	uint8* mPtr;
	

	PtrInfo() :
		mSize(0),
		mPtr(0)
	{}

	PtrInfo(void* newPtr) :
		mSize(0),
		mPtr((uint8*)newPtr)
	{}
};

struct PoolDesc
{
	PoolDesc(const uint32 size, const uint32 numAllocs) :
		mSize(size),
		mNumAllocs(numAllocs)
	{}

	/** Size of the pool. */
	const uint32 mSize;

	/** Number of allocations in the pool. */
	const uint32 mNumAllocs;
};

struct PtrData
{
	uint32 mMask;
	uint32 mSize;
	uint8* mPtr;


	PtrData() :
		mMask(0),
		mSize(0),
		mPtr(0)
	{}

	PtrData(uint32 mask, void* newPtr) :
		mMask(mask),
		mSize(0),
		mPtr((uint8*)newPtr)
	{}
};

struct PtrNode
{
	uint64 mSize;
	PtrNode* mNext;
	uint8* mPtr;
};


class MallocBase
{
public:
	/**
	 * Malloc
	 */
	virtual void* Malloc(uint32 count, uint32 alignment = DEFAULT_ALIGNMENT) = 0;

	/**
	 * TryMalloc - like Malloc(), but may return a nullptr result if the allocation
	 *             request cannot be satisfied.
	 */
	virtual void* TryMalloc(uint32 count, uint32 alignment = DEFAULT_ALIGNMENT);

	/**
	 * Realloc
	 */
	virtual void* Realloc(void* original, uint32 count, uint32 alignment = DEFAULT_ALIGNMENT) = 0;

	/**
	 * TryRealloc - like Realloc(), but may return a nullptr if the allocation
	 *              request cannot be satisfied. Note that in this case the memory
	 *              pointed to by Original will still be valid
	 */
	virtual void* TryRealloc(void* original, uint32 count, uint32 alignment = DEFAULT_ALIGNMENT);

	/**
	 * Free
	 */
	virtual void Free(void* original) = 0;

	/**
	* If possible determine the size of the memory allocated at the given address
	*
	* @param Original - Pointer to memory we are checking the size of
	* @param SizeOut - If possible, this value is set to the size of the passed in pointer
	* @return true if succeeded
	*/
	virtual bool GetAllocationSize(void* original, uint32& sizeOut)
	{
		return false; // Default implementation has no way of determining this
	}

};

